﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;
using System.Security.Cryptography;
using WinFromMediaPlayerDemo.Model;
using WinFromMediaPlayerDemo.Interface;
using System.Threading.Tasks;

namespace WinFromMediaPlayerDemo.Common
{
    /// <summary>
    /// 视频同步器，负责同步云端资源到本地
    /// </summary>
    public class FileHandler
    {

        private string _RemoteResourceUri;
        private string _LocalDirectory;
        public static IMessageProvider _MessageProvider;
        public static string LocalCacheDirecotry
        {
            get
            {
                string defaultCacheDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "zy");
                if(!Directory.Exists(defaultCacheDirectory))
                {
                    Directory.CreateDirectory(defaultCacheDirectory);
                }
                if (!string.IsNullOrEmpty(Global.Default.LocalCacheDirecotry))
                {
                    defaultCacheDirectory = Global.Default.LocalCacheDirecotry;
                }
                return defaultCacheDirectory;
            }
        
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="remoteResourceUri">远程资源地址</param>
        /// <param name="localDirecotry">本地资源地址</param>
        public  FileHandler(string remoteResourceUri,string localDirecotry)
        {
            _RemoteResourceUri = remoteResourceUri;
            _LocalDirectory = localDirecotry;
        }
        /// <summary>
        /// 获取远程文件资源列表
        /// </summary>
        /// <param name="resUri">文件资源列表URL</param>
        /// <returns></returns>
        public static List<RemoteFileInfo> GetRemoteFileList(string resUri,out string message,out int code)
        {
            if(string.IsNullOrEmpty(resUri))
            {
                code = -3;
                message = "视频服务器地址未配置";
                return null;
            }
            code = 0;
            message = "获取文件成功";
            List<RemoteFileInfo> videoInfoList = null;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resUri);
            request.Accept = "application/json,utf-8";
            try
            {
                var response = request.GetResponse();
                using (var s = response.GetResponseStream())
                {
                    using (StreamReader sr = new StreamReader(s))
                    {
                        string jsonString = sr.ReadToEnd();
                        videoInfoList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<RemoteFileInfo>>(jsonString);
                    }
                    
                }
                
            }
            catch (WebException)
            {
                code = -1;
                message = "网络异常，连接服务器失败";
            }
            catch(Exception)
            {
                code = -2;
                message = "系统异常";
            }
            return videoInfoList;
        }


        /// <summary>
        /// 计算视频文件的Hash值
        /// </summary>
        /// <param name="fileFullName">视频文件的全路径</param>
        /// <returns></returns>
        public static string ComputeVideoHash(string fileFullName)
        {
            string hashCode = "";
            if(string.IsNullOrEmpty(fileFullName) || !File.Exists(fileFullName))
            {
                return hashCode;
            }
            SHA1 sha1 = SHA1.Create();
            using(FileStream fs = new FileStream(fileFullName, FileMode.Open))
            {
                byte[] hashData = sha1.ComputeHash(fs);
                StringBuilder sb = new StringBuilder();
                foreach (var item in hashData)
                {
                    sb.Append(item.ToString("X2"));
                }
                hashCode = sb.ToString();
            }
            return hashCode;
        }


        /// <summary>
        /// 获取本地视频列表
        /// </summary>
        /// <returns></returns>
        public static string[] GetLocalCacheFileList()
        {
            return Directory.GetFiles(LocalCacheDirecotry);
        }

        /// <summary>
        /// 写入临时文件
        /// </summary>
        /// <param name="partionFileInfo"></param>
        /// <param name="partionIndex"></param>
        /// <param name="data"></param>
        public static void WriteTempFile(PartionFileInfo partionFileInfo,uint partionIndex,byte[] data)
        {
            RemoteFileInfo fileInfo = partionFileInfo.FileInfo;
            string tempFileDirecotry = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments), fileInfo.FileName);
            string tempFileName = Path.Combine(tempFileDirecotry, $"{partionIndex}.tmp");

            if (!Directory.Exists(tempFileDirecotry))
            {
                Directory.CreateDirectory(tempFileDirecotry);
            }
            using (FileStream fs = new FileStream(tempFileName, FileMode.Create))
            {
                fs.Write(data, 0, data.Length);
            }
            string joinedFileName = Path.Combine(LocalCacheDirecotry, fileInfo.FileName);

            int tmpFilesCount = Directory.GetFiles(tempFileDirecotry).Length;
            if(tmpFilesCount == fileInfo.TotalPartionCount)
            {
                JoinTempFileToSingle(Path.Combine(LocalCacheDirecotry,fileInfo.FileName), tempFileDirecotry);
            }
        }
        /// <summary>
        /// 合并多个临时文件为单个文件
        /// </summary>
        /// <param name="fileInfo"></param>
        /// <param name="tempFileDirecotry"></param>
        /// <param name="partionCount"></param>
        /// <returns></returns>
        public static void JoinTempFileToSingle(string joinedFileName,string tempFileDirecotry)
        {
            string[] tempFiles = Directory.GetFiles(tempFileDirecotry).OrderBy(k=>k,new NumFileNameCompare()).ToArray();
            FileStream joinedFs = new FileStream(joinedFileName, FileMode.Append);
            foreach (var item in tempFiles)
            {
                using (FileStream fs = new FileStream(item, FileMode.Open, FileAccess.Read))
                {
                    fs.CopyTo(joinedFs);
                }
            }
            joinedFs.Close();
            Directory.Delete(tempFileDirecotry,true);
            
        }


        /// <summary>
        /// 检查是否需要升级
        /// </summary>
        /// <returns></returns>
        public static bool IsUpdate()
        {
            string defaultCacheDirectory = LocalCacheDirecotry;
            string message;
            int code;
            var fileInfos = GetRemoteFileList(Global.Default.VideoSererAddress, out message, out code);
            if (code != 0)
            {
                _MessageProvider.Show( message);
                return false;
            }
            if (fileInfos == null)
            {
                return false;
            }
            foreach (var item in fileInfos)
            {
                string currentFileFullName = Path.Combine(defaultCacheDirectory, item.FileName);
                //检查文件是否存在
                if (File.Exists(currentFileFullName) && (ulong)new FileInfo(currentFileFullName).Length == item.FileSize)
                {
                    continue;
                }
                else
                {
                    return true;
                }
            }
            return false;
        }
    }


  
}
